package com.kusen.juc;

/**
 * 多线程开发：1.高内聚，低耦合。2.使用可重入锁。3.线程操作资源类
 * juc的开始学习，使用可重入锁的方式来实现卖票系统
 * <p>
 * 线程的五种状态：创建（NEW）、运行(RUNNABLE)、阻塞(BLOCKED)、等待（WAITING）、死亡（TERMINATED）
 * 所以线程创建的并不是马上执行的。而是等待cpu来分配资源进行dendritic带执行
 * 这就是为啥现在的的程序都是要求有熟悉线程这个能力。因为多线程可以提供系统的服务质量。
 * 原理上，创建了3个线程，但是再运行的时候可能不会在创建3个有可能是一个人干了3个人的活，或者是2个人
 * <p>
 * Lock lock =new ReentrantLock();
 * <p>
 * try{}finally{}
 * 接口可以new,但是抽象类不可以new
 */

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 这是一个资源类
 */
class Ticket {//资源类=实例变量+实例方法
    private int number = 30;

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    Lock lock = new ReentrantLock();

    //买票的方法
    public void sale() {
        //创建锁
        lock.lock();
        try {
            if (number > 0) {
                System.out.println(Thread.currentThread().getName() + "：售卖了第" + number-- + "张票，还剩" + number + "张票");
            }
        } finally {
            //释放锁
            lock.unlock();
        }
    }
}

public class JucText2 {
    public static void main(String[] args) {
        //创建资源类
        Ticket ticker = new Ticket();
        //一个线程相当于现实生活中的一个售票窗口
        //创建3个线程来卖票。使用java8的特性来创建线程 lambda表达是创建线程
        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                ticker.sale();
            }
            ;
        }, "AAA").start();
        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                ticker.sale();
            }
            ;
        }, "BBB").start();
        new Thread(() -> {
            for (int i = 0; i < 40; i++) {
                ticker.sale();
            }
            ;
        }, "CCC").start();
    }
}
